home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Personal Computer World 2005 October
/
PCWOCT05.iso
/
Software
/
FromTheMag
/
XAMPP 1.4.14
/
xampp-win32-1.4.14-installer.exe
/
xampp
/
php
/
pear
/
Image
/
GraphViz.php
< prev
next >
Wrap
PHP Script
|
2004-03-24
|
12KB
|
431 lines
<?php
//
// +---------------------------------------------------------------------------+
// | PEAR :: Image :: GraphViz |
// +---------------------------------------------------------------------------+
// | Copyright (c) 2002-2004 Sebastian Bergmann <sb@sebastian-bergmann.de> and |
// | Dr. Volker G÷bbels <vmg@arachnion.de>. |
// +---------------------------------------------------------------------------+
// | This source file is subject to version 3.00 of the PHP License, |
// | that is available at http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +---------------------------------------------------------------------------+
//
// $Id: GraphViz.php,v 1.21 2004/02/25 10:35:57 sebastian Exp $
//
require_once 'System.php';
/**
* PEAR::Image_GraphViz
*
* Purpose
*
* Allows for the creation of and the work with directed
* and undirected graphs and their visualization with
* AT&T's GraphViz tools. These can be found at
* http://www.research.att.com/sw/tools/graphviz/
*
* Example
*
* require_once 'Image/GraphViz.php';
* $graph = new Image_GraphViz();
*
* $graph->addNode('Node1', array('URL' => 'http://link1',
* 'label' => 'This is a label',
* 'shape' => 'box'
* )
* );
* $graph->addNode('Node2', array('URL' => 'http://link2',
* 'fontsize' => '14'
* )
* );
* $graph->addNode('Node3', array('URL' => 'http://link3',
* 'fontsize' => '20'
* )
* );
*
* $graph->addEdge(array('Node1' => 'Node2'), array('label' => 'Edge Label'));
* $graph->addEdge(array('Node1' => 'Node2'), array('color' => 'red'));
*
* $graph->image();
*
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
* Dr. Volker G÷bbels <vmg@arachnion.de>
* @package Image
*/
class Image_GraphViz {
/**
* Path to GraphViz/dot command
*
* @var string
*/
var $dotCommand = 'dot';
/**
* Path to GraphViz/neato command
*
* @var string
*/
var $neatoCommand = 'neato';
/**
* Representation of the graph
*
* @var array
*/
var $graph;
/**
* Constructor
*
* @param boolean Directed (true) or undirected (false) graph.
* @param array Attributes of the graph
* @access public
*/
function Image_GraphViz($directed = true, $attributes = array()) {
$this->setDirected($directed);
$this->setAttributes($attributes);
}
/**
* Output image of the graph in a given format.
*
* @param string Format of the output image.
* This may be one of the formats supported by GraphViz.
* @access public
*/
function image($format = 'svg') {
if ($file = $this->saveParsedGraph()) {
$outputfile = $file . '.' . $format;
$command = $this->graph['directed'] ? $this->dotCommand : $this->neatoCommand;
$command .= " -T$format -o$outputfile $file";
@`$command`;
@unlink($file);
$sendContentLengthHeader = true;
switch ($format) {
case 'gif':
case 'png':
case 'wbmp': {
header('Content-Type: image/' . $format);
}
break;
case 'jpg': {
header('Content-Type: image/jpeg');
}
break;
case 'pdf': {
header('Content-Type: application/pdf');
}
break;
case 'svg': {
header('Content-Type: image/svg+xml');
}
break;
default: {
$sendContentLengthHeader = false;
}
}
if ($sendContentLengthHeader) {
header('Content-Length: ' . filesize($outputfile));
}
$fp = fopen($outputfile, 'rb');
if ($fp) {
echo fread($fp, filesize($outputfile));
fclose($fp);
@unlink($outputfile);
}
}
}
/**
* Add a cluster to the graph.
*
* @param string ID.
* @param array Title.
* @access public
*/
function addCluster($id, $title) {
$this->graph['clusters'][$id] = $title;
}
/**
* Add a note to the graph.
*
* @param string Name of the node.
* @param array Attributes of the node.
* @param string Group of the node.
* @access public
*/
function addNode($name, $attributes = array(), $group = 'default') {
$this->graph['nodes'][$group][$name] = $attributes;
}
/**
* Remove a node from the graph.
*
* @param Name of the node to be removed.
* @access public
*/
function removeNode($name, $group = 'default') {
if (isset($this->graph['nodes'][$group][$name])) {
unset($this->graph['nodes'][$group][$name]);
}
}
/**
* Add an edge to the graph.
*
* @param array Start and End node of the edge.
* @param array Attributes of the edge.
* @access public
*/
function addEdge($edge, $attributes = array()) {
if (is_array($edge)) {
$from = key($edge);
$to = $edge[$from];
$id = $from . '_' . $to;
if (!isset($this->graph['edges'][$id])) {
$this->graph['edges'][$id] = $edge;
} else {
$this->graph['edges'][$id] = array_merge(
$this->graph['edges'][$id],
$edge
);
}
if (is_array($attributes)) {
if (!isset($this->graph['edgeAttributes'][$id])) {
$this->graph['edgeAttributes'][$id] = $attributes;
} else {
$this->graph['edgeAttributes'][$id] = array_merge(
$this->graph['edgeAttributes'][$id],
$attributes
);
}
}
}
}
/**
* Remove an edge from the graph.
*
* @param array Start and End node of the edge to be removed.
* @access public
*/
function removeEdge($edge) {
if (is_array($edge)) {
$from = key($edge);
$to = $edge[$from];
$id = $from . '_' . $to;
if (isset($this->graph['edges'][$id])) {
unset($this->graph['edges'][$id]);
}
if (isset($this->graph['edgeAttributes'][$id])) {
unset($this->graph['edgeAttributes'][$id]);
}
}
}
/**
* Add attributes to the graph.
*
* @param array Attributes to be added to the graph.
* @access public
*/
function addAttributes($attributes) {
if (is_array($attributes)) {
$this->graph['attributes'] = array_merge(
$this->graph['attributes'],
$attributes
);
}
}
/**
* Set attributes of the graph.
*
* @param array Attributes to be set for the graph.
* @access public
*/
function setAttributes($attributes) {
if (is_array($attributes)) {
$this->graph['attributes'] = $attributes;
}
}
/**
* Set directed/undirected flag for the graph.
*
* @param boolean Directed (true) or undirected (false) graph.
* @access public
*/
function setDirected($directed) {
if (is_bool($directed)) {
$this->graph['directed'] = $directed;
}
}
/**
* Load graph from file.
*
* @param string File to load graph from.
* @access public
*/
function load($file) {
if ($serialized_graph = implode('', @file($file))) {
$this->graph = unserialize($serialized_graph);
}
}
/**
* Save graph to file.
*
* @param string File to save the graph to.
* @return mixed File the graph was saved to, false on failure.
* @access public
*/
function save($file = '') {
$serialized_graph = serialize($this->graph);
if (empty($file)) {
$file = System::mktemp('graph_');
}
if ($fp = @fopen($file, 'w')) {
@fputs($fp, $serialized_graph);
@fclose($fp);
return $file;
}
return false;
}
/**
* Parse the graph into GraphViz markup.
*
* @return string GraphViz markup
* @access public
*/
function parse() {
$parsedGraph = "digraph G {\n";
if (isset($this->graph['attributes'])) {
foreach ($this->graph['attributes'] as $key => $value) {
$attributeList[] = $key . '="' . $value . '"';
}
if (!empty($attributeList)) {
$parsedGraph .= implode(',', $attributeList) . ";\n";
}
}
if (isset($this->graph['nodes'])) {
foreach($this->graph['nodes'] as $group => $nodes) {
if ($group != 'default') {
$parsedGraph .= sprintf(
"subgraph \"cluster_%s\" {\nlabel=\"%s\";\n",
$group,
isset($this->graph['clusters'][$group]) ? $this->graph['clusters'][$group] : ''
);
}
foreach($nodes as $node => $attributes) {
unset($attributeList);
foreach($attributes as $key => $value) {
$attributeList[] = $key . '="' . $value . '"';
}
if (!empty($attributeList)) {
$parsedGraph .= sprintf(
"\"%s\" [ %s ];\n",
addslashes(stripslashes($node)),
implode(',', $attributeList)
);
}
}
if ($group != 'default') {
$parsedGraph .= "}\n";
}
}
}
if (isset($this->graph['edges'])) {
foreach($this->graph['edges'] as $label => $node) {
unset($attributeList);
$from = key($node);
$to = $node[$from];
foreach($this->graph['edgeAttributes'][$label] as $key => $value) {
$attributeList[] = $key . '="' . $value . '"';
}
$parsedGraph .= sprintf(
'"%s" -> "%s"',
addslashes(stripslashes($from)),
addslashes(stripslashes($to))
);
if (!empty($attributeList)) {
$parsedGraph .= sprintf(
' [ %s ]',
implode(',', $attributeList)
);
}
$parsedGraph .= ";\n";
}
}
return $parsedGraph . "}\n";
}
/**
* Save GraphViz markup to file.
*
* @param string File to write the GraphViz markup to.
* @return mixed File to which the GraphViz markup was
* written, false on failure.
* @access public
*/
function saveParsedGraph($file = '') {
$parsedGraph = $this->parse();
if (!empty($parsedGraph)) {
if (empty($file)) {
$file = System::mktemp('graph_');
}
if ($fp = @fopen($file, 'w')) {
@fputs($fp, $parsedGraph);
@fclose($fp);
return $file;
}
}
return false;
}
}
?>